package com.acme.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * This class gets information about {@link TestArrived} class
 *
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class Analyzer {
    public static void main(final String[] args) {
        Class clazz = TestArrived.class;
        System.out.println("class name:");
        System.out.println("-----------------------------------");
        System.out.println("\t" + clazz.getName());
        System.out.println("===================================");

        System.out.println("class annotations:");
        System.out.println("-----------------------------------");
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println("\t" + annotation);
        }
        System.out.println("===================================");

        int modifiers = clazz.getModifiers();
        System.out.println("class modifiers:");
        System.out.println("-----------------------------------");
        if (Modifier.isAbstract(modifiers)) {
            System.out.println("\tabstract");
        }
        if (Modifier.isFinal(modifiers)) {
            System.out.println("\tfinal");
        }
        if (Modifier.isInterface(modifiers)) {
            System.out.println("\tinterface");
        }
        System.out.println("===================================");

        System.out.println("package:");
        System.out.println("-----------------------------------");
        System.out.println("\t" + clazz.getPackage().getName());
        System.out.println("===================================");

        System.out.println("class hierarchy:");
        System.out.println("-----------------------------------");
        System.out.println("\t" + clazz.getName());
        Class superclass = clazz.getSuperclass();
        do {
            System.out.println("\t" + superclass.getName());
            superclass = superclass.getSuperclass();
        } while (!superclass.equals(Object.class));
        System.out.println("===================================");

        System.out.println("class interfaces:");
        System.out.println("-----------------------------------");
        for (Class interfaze : clazz.getInterfaces()) {
            System.out.println("\t" + interfaze.getName());
        }
        System.out.println("===================================");

        System.out.println("class fields:");
        System.out.println("-----------------------------------");
        for (Field field : clazz.getDeclaredFields()) {
            System.out.println("\t" + field.getName());
            System.out.println("\t\ttype: " + field.getType().getName());
        }
        System.out.println("===================================");

        System.out.println("class methods:");
        System.out.println("-----------------------------------");
        for (Method method : clazz.getDeclaredMethods()) {
            System.out.println("\t" + method.getName());
            System.out.println("\t\tparameters:");
            for (Class param : method.getParameterTypes()) {
                System.out.println("\t\t\t" + param.getName());
            }
            System.out.println("\t\tannotations:");
            for (Annotation annotation : method.getAnnotations()) {
                System.out.println("\t\t\t" + annotation);
            }
            System.out.println("\t\texceptions:");
            for (Class exception : method.getExceptionTypes()) {
                System.out.println("\t\t\t" + exception.getName());
            }
        }
        System.out.println("===================================");

        System.out.println("class constructors:");
        System.out.println("-----------------------------------");
        for (Constructor constructor : clazz.getDeclaredConstructors()) {
            System.out.println("\t" + constructor.getName());
            System.out.println("\t\tparameters:");
            for (Class param : constructor.getParameterTypes()) {
                System.out.println("\t\t\t" + param.getName());
            }
            System.out.println("\t\tannotations:");
            for (Annotation annotation : constructor.getAnnotations()) {
                System.out.println("\t\t\t" + annotation);
            }
            System.out.println("\t\texceptions:");
            for (Class exception : constructor.getExceptionTypes()) {
                System.out.println("\t\t\t" + exception.getName());
            }
        }
    }
}
